package com.wrb.exceptionhandler;


import com.wrb.entity.Response;
import com.wrb.entity.ResponseStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.method.annotation.ExceptionHandlerMethodResolver;
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
import org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author haixingchen
 */
@Slf4j
public class ExceptionHandler extends ExceptionHandlerExceptionResolver {
    private final Map<Class<?>, ExceptionHandlerMethodResolver> exceptionHandlerMethodResolvers = new ConcurrentHashMap();

    @Override
    protected ServletInvocableHandlerMethod getExceptionHandlerMethod(HandlerMethod handlerMethod, Exception exception) {
        Class<?> handlerType = handlerMethod != null ? handlerMethod.getBeanType() : null;
        if(handlerType!=null){
            Method method = this.getExceptionHandlerMethodResolver(handlerType).resolveMethod(exception);
            if (method != null) {
                return new ServletInvocableHandlerMethod(handlerMethod.getBean(), method);
            } else {
                try {
                    method = this.getClass().getMethod("getFailedResult", Exception.class);
                } catch (Exception var6) {
                    log.error("异常处理类处理信息失败！");
                }
                return new ServletInvocableHandlerMethod(this, method);
            }
        }
        return null;
    }

    @ResponseBody
    public Response getFailedResult(Exception exception) {
        String s = UUID.randomUUID().toString();
        log.error("异常Id->"+s );
        if(exception instanceof MethodArgumentNotValidException) {
            BindingResult bindingResult = ((MethodArgumentNotValidException)exception).getBindingResult();
            String message = null;
            if (bindingResult.hasErrors()) {
                FieldError fieldError = bindingResult.getFieldError();
                if (fieldError != null) {
                    message = fieldError.getField() + fieldError.getDefaultMessage();
                }
            }
            return Response.fail(ResponseStatus.FILED_ERROR.setMsg("异常编号: "+s+"异常信息: "+message+",请联系开发人员处理！"));
        }
        exception.printStackTrace();
        Response response = new Response();
        response.setCode("-1");
        response.setMsg("异常编号: "+s+"异常信息: "+ exception.getMessage()+",请联系开发人员处理！");
        return response;
    }

    private ExceptionHandlerMethodResolver getExceptionHandlerMethodResolver(Class<?> handlerType) {
        ExceptionHandlerMethodResolver resolver =  this.exceptionHandlerMethodResolvers.get(handlerType);
        if (resolver == null) {
            resolver = new ExceptionHandlerMethodResolver(handlerType);
            this.exceptionHandlerMethodResolvers.put(handlerType, resolver);
        }
        return resolver;
    }
}